#include <sys/signal.h>
#include <iostream>
#include <thread>
#include <sand.h>
#include "yaml.h"
#include "asynctimerqueue.h"
#include "traffic_data_process.h"
//#include "spdlog/spdlog.h"

#define asyncTimerObj Timer::AsyncTimerQueue::Instance()

int main(int argc, char *argv[]) {
    //auto file_logger = spdlog::rotating_logger_mt("file_logger", "logs/mylogfile", 1024 * 1024 * 5, 3);
    //file_logger->info("Log file message number", 1);
    //auto console = spdlog::stdout_logger_mt("console");
    //spdlog::set_level(spdlog::level::debug);
    //console->info("traffic statistics start");
    //console->info("traffic statistics start");

    TrafficProcess  traffic;
    TrafficProcess::Yaml_Config_ST config_st;
    std::string sqlite3_db_file;
    std::string traffic_data_file;
    uint32_t  data_collect_interval = 5;
    uint32_t data_dump_at_minute = 0;
    uint32_t data_dump_at_hour = 0;

    std::string yaml_config_file = "./config/traffic.yaml";
    YAML::Node root = YAML::LoadFile(yaml_config_file);
    if (root) {
        for (auto it=root.begin(); it!=root.end(); ++it) {
            if (it->first && it->first.as<std::string>().compare("general") == 0) {
                if (it->second["sqlite3_db_file"] && !it->second["sqlite3_db_file"].IsNull()) {
                    sqlite3_db_file = it->second["sqlite3_db_file"].as<std::string>();
                    config_st.db_file = sqlite3_db_file;
                }
                if (it->second["traffic_data_file"] && !it->second["traffic_data_file"].IsNull()) {
                    traffic_data_file = it->second["traffic_data_file"].as<std::string>();
                    config_st.data_file = traffic_data_file;
                }
                if (it->second["data_collect_interval"] && !it->second["data_collect_interval"].IsNull()) {
                    data_collect_interval = it->second["data_collect_interval"].as<uint32_t>();
                    config_st.collect_interval = data_collect_interval;
                }
                if (it->second["data_dump_at_minute"] && !it->second["data_dump_at_minute"].IsNull()) {
                    data_dump_at_minute = it->second["data_dump_at_minute"].as<uint32_t>();
                    config_st.dump_at_minute = data_dump_at_minute;
                }
                if (it->second["data_dump_at_hour"] && !it->second["data_dump_at_hour"].IsNull()) {
                    data_dump_at_hour = it->second["data_dump_at_hour"].as<uint32_t>();
                    config_st.dump_at_hour = data_dump_at_hour;
                }
                traffic.set_yaml_config(config_st);
            }
        }
    }
    //console->info("read config file complete");

    int eventid1 = 0;
    int eventid2 = 0;
    int eventid3 = 0;

    std::thread asyncthread(&Timer::AsyncTimerQueue::timerLoop, &asyncTimerObj);

    while(1) {
        int64_t this_time = sand::now();
        int this_minute = sand::minute(this_time);
        std::cout<<"current minute is :"<<this_minute<<std::endl;

        if (this_minute % data_collect_interval == 0) {
            eventid1 = asyncTimerObj.create(1000, false, &TrafficProcess::data_to_memory, &traffic);
        }

        if (this_minute == data_dump_at_minute) {
            eventid2 = asyncTimerObj.create(1000*10, false, &TrafficProcess::data_store_by_hour, &traffic);
        }

        int64_t exec_datetime = sand::datetime(sand::year(this_time),
                                               sand::month(this_time),
                                               sand::day(this_time),
                                               data_dump_at_hour, 59, 59);
        int64_t diff_time = exec_datetime - this_time;
        if (diff_time >= 0 && diff_time <= 1000*59) {
            eventid3 = asyncTimerObj.create(1000*60, false, &TrafficProcess::data_store_by_day, &traffic);
        }

        std::this_thread::sleep_for(std::chrono::seconds(60));
        asyncTimerObj.reset_start_time();
    }

    //asyncTimerObj.shutdown();
    //asyncthread.join();

    return 0;
}